package com.ybu.oodd.service.impl;

import com.ybu.oodd.mapper.UserMapper;
import com.ybu.oodd.myenum.ErrorType;
import com.ybu.oodd.myenum.LoginType;
import com.ybu.oodd.pojo.*;
import com.ybu.oodd.service.UserService;
import com.ybu.oodd.utils.aes.AESUtil;
import com.ybu.oodd.utils.code.CodeUtils;
import com.ybu.oodd.utils.email.MailUtils;
import com.ybu.oodd.utils.login.ContextHolder;
import com.ybu.oodd.utils.login.JwtUtils;
import com.ybu.oodd.utils.oss.AliyunOSSOperator;
import com.ybu.oodd.utils.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.swing.*;
import java.time.LocalDateTime;
import java.util.*;

import static java.time.LocalDateTime.now;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MailUtils mailUtils;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private AliyunOSSOperator aliyunOSSOperator;

    /*
     * 用户登录
     * */
    @Override
    public Result login(UserLogin userLogin) {
        //1.邮箱密码登录
        if(userLogin.getLoginType() == LoginType.emailpassword){
            //检验是否为空
            if(userLogin.getEmail()==null||userLogin.getEmail().isEmpty()){
                return Result.error(ErrorType.NullEmail.toString());
            }
            if(userLogin.getPassword()==null||userLogin.getPassword().isEmpty()){
                return Result.error(ErrorType.NullPassword.toString());
            }
            //检验是否已经注册
            if(!userMapper.getEmail(userLogin.getEmail())){
                //没有注册
                return Result.error(ErrorType.NoExitsEmail.toString());
            }
            //验证密码
            userLogin.setPassword(AESUtil.decrypt(userLogin.getPassword()));//解密
            if(!userLogin.getPassword().equals(userMapper.getPasswordByEmail(userLogin.getEmail()))){
                return Result.error(ErrorType.PasswordError.toString());
            }
            //生成token
            Map<String, Object> claims = new HashMap<>();
            Integer userId = userMapper.getUserIdByEmail(userLogin.getEmail());
            claims.put("userId",userId);
            String token = JwtUtils.generateJwt(claims);

            //存入redis
            redisUtil.set(userId.toString(),token,432000L);//5天
            return Result.success("登录成功",token);
        }

        //2.电话密码登录
        else if(userLogin.getLoginType() == LoginType.phonepassword){
            //检验是否为空
            if(userLogin.getPhone()==null||userLogin.getPhone().isEmpty()){
                return Result.error(ErrorType.NullPhone.toString());
            }
            if(userLogin.getPassword()==null||userLogin.getPassword().isEmpty()){
                return Result.error(ErrorType.NullPassword.toString());
            }
            //检验是否已经注册
            if(!userMapper.getPhone(userLogin.getPhone())){
                //没有注册
                return Result.error(ErrorType.NoExitsPhone.toString());
            }
            //验证密码
            if(!userLogin.getPassword().equals(userMapper.getPasswordByPhone(userLogin.getPhone()))){
                return Result.error(ErrorType.PasswordError.toString());
            }
            //生成token
            Map<String, Object> claims = new HashMap<>();
            Integer userId = userMapper.getUserIdByPhone(userLogin.getPhone());
            claims.put("userId",userId);
            String token = JwtUtils.generateJwt(claims);

            //存入redis
            redisUtil.set(userId.toString(),token,432000L);//5天
            return Result.success("登录成功",token);
        }

        //3.邮箱验证码登录
        else if (userLogin.getLoginType() == LoginType.emailcode) {
            //检验是否为空
            if(userLogin.getEmail().isEmpty()){
                return Result.error(ErrorType.NullEmail.toString());
            }
            if(userLogin.getCode().isEmpty()){
                return Result.error(ErrorType.NullCode.toString());
            }
            //验证邮箱验证码
            String rcode = (String) redisUtil.get(userLogin.getEmail());
            //是否过期
            if(rcode==null||rcode==""){
                return Result.error(ErrorType.CodeExpired.toString());
            }
            //是否一致
            if(!rcode.equals(userLogin.getCode())){
                return Result.error(ErrorType.CodeError.toString());
            }
            //删除redis中的code
            redisUtil.delete(userLogin.getEmail());
            //生成token
            Map<String, Object> claims = new HashMap<>();
            Integer userId = userMapper.getUserIdByEmail(userLogin.getEmail());
            claims.put("userId",userId);
            String token = JwtUtils.generateJwt(claims);

            //存入redis
            redisUtil.set(userId.toString(),token,432000L);//5天
            return Result.success("登录成功",token);
        }
        //4.手机验证码登录
        else{

        }
        return Result.error(ErrorType.LoginError.toString());
    }

    /*
     * 获取验证码请求
     * */
    @Override
    public ErrorType getCode(UserLogin userLogin) {
        //邮箱验证码
        if(userLogin.getLoginType() == LoginType.emailcode){
            //发送邮箱验证码
            String code = CodeUtils.generateCode(6);
            Set<String> set = new HashSet<>();
            set.add(userLogin.getEmail());
            mailUtils.sendEmail(set,code);

            //存入redis
            redisUtil.set(userLogin.getEmail(),code,300L);//300s 5m
            return null;
        }
        //电话验证码
        else if (userLogin.getLoginType() == LoginType.phonecode) {
            //发送电话验证码
            //存入redis
            return null;
        }
        return ErrorType.error;
    }

    /*
     * 用户注册
     * */
    @Override
    public ErrorType register(UserLogin userLogin) {
        //邮箱验证码
        if(userLogin.getLoginType() == LoginType.emailcode){
            //检验是否已经注册
            if(userMapper.getEmail(userLogin.getEmail())){
                //已经注册
                return ErrorType.ExitsEmail;
            }
            //验证邮箱验证码
            String rcode = (String) redisUtil.get(userLogin.getEmail());
            //是否过期
            if(rcode==null || rcode==""){
                return ErrorType.CodeExpired;
            }
            //是否一致
            if(!rcode.equals(userLogin.getCode())){
                return ErrorType.CodeError;
            }
            //删除redis中的code
            redisUtil.delete(userLogin.getEmail());

            //解密
            userLogin.setPassword(AESUtil.decrypt(userLogin.getPassword()));

            //写入数据库
            User user = new User()
                    .setEmail(userLogin.getEmail())
                    .setPassWord(userLogin.getPassword())
                    .setFreeNum(5)
                    .setCreateTime(now())
                    .setUpdateTime(now());
            userMapper.saveUser(user);
            return null;
        }
        //电话验证码
        else if (userLogin.getLoginType() == LoginType.phonecode) {
            //检验是否已经注册
            if(userMapper.getPhone(userLogin.getPhone())){
                //已经注册
                return ErrorType.NoExitsPhone;
            }
            //验证电话验证码
            return null;
        }
        return ErrorType.error;
    }

    /*
     * 修改密码
     * */
    @Override
    public ErrorType updatePassword(UserLogin userLogin) {
        //邮箱验证码
        if(userLogin.getLoginType() == LoginType.emailcode){
            //验证邮箱验证码
            String rcode = (String) redisUtil.get(userLogin.getEmail());
            //是否过期
            if(rcode==null || rcode==""){
                return ErrorType.CodeExpired;
            }
            //是否一致
            if(!rcode.equals(userLogin.getCode())){
                return ErrorType.CodeError;
            }

            //解密
            userLogin.setPassword(AESUtil.decrypt(userLogin.getPassword()));
            userLogin.setOldPassword(AESUtil.decrypt(userLogin.getOldPassword()));

            //验证 旧密码
            if(!userLogin.getOldPassword().equals(userMapper.getPasswordByEmail(userLogin.getEmail()))){
                return ErrorType.OldPasswordError;
            }

            //删除redis中的code
            redisUtil.delete(userLogin.getEmail());

            //修改
            userMapper.updatePassword(ContextHolder.get("userId"),userLogin.getPassword());

            return null;
        }
        //电话验证码
        else if (userLogin.getLoginType() == LoginType.phonecode) {
            //验证电话验证码
            return null;
        }
        return ErrorType.error;
    }

    /*
     * 修改密码时，获取验证
     * */
    @Override
    public ErrorType updatePasswordGetCode(UserLogin userLogin) {
        //邮箱验证码
        if(userLogin.getLoginType() == LoginType.emailcode){
            //根据id检验email是否一致
            String email = userMapper.getEmailByid(ContextHolder.get("userId"));
            if(!userLogin.getEmail().equals(email)){
                //不一致
                return ErrorType.EmailError;
            }
            //发送验证码
            return getCode(userLogin);
        }
        //电话验证码
        else if (userLogin.getLoginType() == LoginType.phonecode) {
            //根据id检验phone是否一致
            String phone = userMapper.getPhoneByid(ContextHolder.get("userId"));
            if(!userLogin.getPhone().equals(phone)){
                //不一致
                return ErrorType.PhoneError;
            }
            //发送验证码
            return getCode(userLogin);
        }
        return null;
    }

    /*
     * 查询用户信息
     * */
    @Override
    public User getUserInfo() {
        User user = userMapper.getUserInfo(ContextHolder.get("userId"));
        LocalDateTime now = LocalDateTime.now();
        user.setIsVip(user.getJobVipEndTime() != null && user.getJobVipEndTime().isAfter(now));
        return user;
    }

    /*
     * VIP校验
     * */
    @Override
    public List<Integer> getVipUserId() {
        return userMapper.getVipUserId();
    }

    /*
     * 免费查询次数>0 用户集合
     * */
    @Override
    public  List<Map<Integer,Integer>> getFreeUserId() {
        return userMapper.getFreeUserId();
    }

    /*
     * 扣减免费查询次数
     * */
    @Override
    public void downFreeNum(Integer userId) {
        userMapper.downFreeNum(userId);
    }

    /*
     * 用户添加问题
     * */
    @Override
    public void saveUserProblem(Problem problem) {
        problem.setUserId(ContextHolder.get("userId"));
        problem.setCreateTime(now());
        userMapper.saveUserProblem(problem);
    }

    /*
     * 用户查询问题
     * */
    @Override
    public List<Problem> getUserProblem() {
        Integer id = ContextHolder.get("userId");
        return userMapper.getUserProblem(id);
    }

    /*
     * 用户修改问题
     * */
    @Override
    public void updateUserProblem(Problem problem) {
        problem.setUserId(ContextHolder.get("userId"));
        userMapper.updateUserProblem(problem);
    }

    /*
     * 用户删除问题
     * */
    @Override
    public void deleteUserProblem(Integer id) {
        userMapper.deleteUserProblem((Integer)ContextHolder.get("userId"),id);
    }

    /*
     * 用户上传文件
     * */
    @Override
    public Pictures upload(MultipartFile file) throws Exception{
        if (!file.isEmpty()) {
            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String extName = originalFilename.substring(originalFilename.lastIndexOf("."));
            String uniqueFileName = UUID.randomUUID().toString().replace("-", "") + extName;
            // 上传文件
            String url = aliyunOSSOperator.upload(file.getBytes(), uniqueFileName);
            // 保存url和userId 返回id
            Pictures p = new Pictures().setUserId(ContextHolder.get("userId")).setUrl(url);
            userMapper.savePicture(p);
            return p;
        }
        return null;
    }

    /*
     * 根据id和user_id 查询url
     * */
    @Override
    public List<Pictures> getPictureUrl(List<Integer> ids) {
        return userMapper.getPictureUrl(ContextHolder.get("userId"),ids);
    }
}
